#include <SFML/System/Thread.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/Sleep.hpp>
#include "bga/system/Timer.h"
#include "bga/system/TimerListener.h"
#include <iostream>

namespace bga
{

void startTimer(void* datas)
{
    Timer* timer = static_cast<Timer*>(datas);
    sf::Clock c;
    c.Reset();
    while(timer->isRunning)
    {
        if(timer->time > 0)
        {
            unsigned int  remainingTime = timer->time - c.GetElapsedTime();
            //std::cout << "ccccc" << std::endl;
            if(remainingTime > 0)
            {
                sf::Sleep(timer->time - c.GetElapsedTime());    /// the current thread is sleeping during the time before launching the event
            }
            //sf::Sleep(timer->time);
            c.Reset();
        }

        TimerEvent event(*timer);
        for(unsigned int i = 0; i < timer->timerListeners.size(); i++)
        {
            timer->timerListeners[i]->timeElapsed(event);
        }
    }
}

Timer::Timer(unsigned int  time) : time(time), isRunning(false)
{
    this->thread = new sf::Thread(startTimer, this);
}

Timer::~Timer()
{
    this->stop();
    if(this->thread != NULL)
    {
        this->thread->Wait();
        delete this->thread;
        this->thread = NULL;
    }
}

void Timer::start()
{
    this->isRunning = true;
    this->thread->Launch();
}

void Timer::stop()
{
    this->isRunning = false;
}

void Timer::setTime(unsigned int  time)
{
    if(!isRunning)
    {
        this->time = time;
    }
}

bool Timer::isStarted() const
{
    return this->isRunning;
}

void Timer::addTimerListener(TimerListener& listener)
{
    this->timerListeners.push_back(&listener);
}

}
